package com.chengjj.kings.core.aop;

import cn.hutool.json.JSONUtil;
import com.chengjj.kings.core.common.annotation.Difftime;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Author: 成俊杰
 * @CreateDate: 2019/3/13
 * @Version: 1.0
 * @Description: 切面:方法执行时间大于期望的时间时，打印警告日志
 */
@Slf4j
@Component
@Aspect
@Order(1)
public class DifftimeAspect {
    @Pointcut(value = "@annotation(difftime) && execution(public * *(..))")
    private void pointcut(Difftime difftime) {

    }

    @Around(value = "pointcut(difftime)", argNames = "joinPoint,difftime")
    public Object arount(ProceedingJoinPoint joinPoint, Difftime difftime) throws Throwable {
        Object resultVal = null;
        Object[] args = joinPoint.getArgs();
        Long start = System.currentTimeMillis();
        resultVal = joinPoint.proceed(args);
        Long end = System.currentTimeMillis();
        long diffTime = end - start;
        if (diffTime > difftime.difftime()) {
            String paramStr = null;
            if (args != null) {
                try {
                    paramStr = JSONUtil.toJsonStr(args);
                } catch (Exception e) {
                    paramStr = Arrays.toString(args);
                }
            }
            String resultStr = null;
            if (resultVal != null) {
                try {
                    resultStr = JSONUtil.toJsonStr(resultVal);
                } catch (Exception e) {
                    resultStr = resultVal.toString();
                }
            }
            log.warn("{} [{}], params:{}, time{}ms > {}ms(expect time)", difftime.desc(), joinPoint.getSignature(), paramStr, resultStr, diffTime, difftime.difftime());
        }
        return resultVal;
    }
}
